package com.run.runbbs.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.run.runbbs.common.dto.ListVO;
import com.run.runbbs.common.dto.PageContent;
import com.run.runbbs.common.lang.Result;
import com.run.runbbs.entity.IndexData;
import com.run.runbbs.entity.UserInfo;
import com.run.runbbs.service.IndexDataService;
import com.run.runbbs.service.UserInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/indexData")
public class IndexDataController {

    @Resource
    UserInfoService userInfoService;

    @Resource
    IndexDataService indexDataService;

    @PostMapping("list")
    public Result list(@RequestBody @Valid ListVO listVO) {

        Page<IndexData> page = new Page<>(listVO.getPage(), listVO.getPageSize());

        IPage<IndexData> iPage = indexDataService.page(page);

        List<IndexData> list = iPage.getRecords();
        list.forEach(indexData -> {
            UserInfo userInfo = userInfoService.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserId, indexData.getUserId()).select(UserInfo::getRealname));
            indexData.setRealName(userInfo.getRealname());
        });

        return Result.success(
                PageContent.<IndexData>builder()
                .columns(null)
                .list(iPage.getRecords())
                .total(iPage.getTotal()).build());
    }

    @GetMapping("export")
    public void export(HttpServletResponse response, HttpServletRequest request) {
        ExcelWriter writer = ExcelUtil.getWriter();

        Map<String, String> excelHeaderMap = new LinkedHashMap<>();
        excelHeaderMap.put("realName", "姓名");
        excelHeaderMap.put("weight", "体重");
        excelHeaderMap.put("temperature", "体温");
        excelHeaderMap.put("sphygmus", "脉搏");
        excelHeaderMap.put("bloodGlucoseLimosis", "空腹血糖");
        excelHeaderMap.put("bloodGlucoseMeal", "餐后2h血糖");
        excelHeaderMap.put("uricAcid", "尿酸");
        excelHeaderMap.put("totalCholesterol", "总胆固醇");
        excelHeaderMap.put("diastolicPressure", "舒张压");
        excelHeaderMap.put("systolicPressure", "收缩压");
        excelHeaderMap.put("createTime", "创建时间");

        excelHeaderMap.forEach(writer::addHeaderAlias);
        String fileName = "居民健康数据.xls";
        getExcel(response, writer,
                indexDataService.list().stream().map(indexData -> {
                    UserInfo userInfo = userInfoService.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserId, indexData.getUserId()).select(UserInfo::getRealname));
                    indexData.setRealName(userInfo.getRealname());

                    JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(indexData, SerializerFeature.WriteNullStringAsEmpty));
                    Map lineContent = new LinkedHashMap();
                    excelHeaderMap.keySet().stream().forEach(b -> lineContent.put(b, jsonObject.getString(b)));
                    return lineContent;
                }).collect(Collectors.toList()),
                fileName);
    }

    public static void getExcel(HttpServletResponse response, ExcelWriter writer, List rows, String fileName) {
        writer.write(rows, true);
        outputFile(response, writer, fileName);
    }



    @GetMapping("downloadTemplate")
    public void downloadTemplate(HttpServletResponse response, HttpServletRequest request) {
        ExcelWriter writer = ExcelUtil.getWriter();
        String fileName = "健康数据输入模板.xls";
        List<String> header = CollUtil.newArrayList("姓名", "体重", "体温", "脉搏", "空腹血糖", "餐后2h血糖", "尿酸", "总胆固醇", "舒张压", "收缩压");
        writer.writeHeadRow(header);
        outputFile(response, writer, fileName);
    }

    private static void outputFile(HttpServletResponse response, ExcelWriter writer, String fileName) {
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            ServletOutputStream out = response.getOutputStream();
            writer.flush(out, true);
            writer.close();
            IoUtil.close(out);
        } catch (Exception e) {
            log.error("文件生成失败 " + e.toString());
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }

    @PostMapping("uploadIndexData")
    public Result upload(@RequestParam(name = "file") MultipartFile indexDataExcel) {
        ExcelReader reader;

        try {
            reader = ExcelUtil.getReader(indexDataExcel.getInputStream());
            List<List<Object>> allData = reader.read();
            List<IndexData> indexDataList = new ArrayList<>();
            for (List<Object> row : allData) {
                log.info(row.toString());
                String realName = (String) row.get(0);
                UserInfo userInfo = userInfoService.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getRealname, realName).select(UserInfo::getUserId));
                if (userInfo == null) continue;
                IndexData indexData = new IndexData();
                indexData.setUserId(userInfo.getUserId())
                        .setWeight(Double.parseDouble(row.get(1).toString()))
                        .setTemperature(Double.parseDouble(row.get(2).toString()))
                        .setSphygmus(Double.parseDouble(row.get(3).toString()))
                        .setBloodGlucoseLimosis(Double.parseDouble(row.get(4).toString()))
                        .setBloodGlucoseMeal(Double.parseDouble(row.get(5).toString()))
                        .setUricAcid(Double.parseDouble(row.get(6).toString()))
                        .setTotalCholesterol(Double.parseDouble(row.get(7).toString()))
                        .setDiastolicPressure(Double.parseDouble(row.get(8).toString()))
                        .setSystolicPressure(Double.parseDouble(row.get(9).toString()))
                        .setCreateTime(new Date())
                        .setDelFlag(0);
                indexDataList.add(indexData);
            }
            indexDataService.saveBatch(indexDataList);
        } catch (IOException e) {
            log.error("IO异常 {}", String.valueOf(e));
        }

        return Result.success(null);
    }
}
